package CoreJAV;

import java.awt.*;
import java.awt.event.*;
import java.io.*;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.tree.*;
import javax.xml.parsers.*;

import org.w3c.dom.*;
import org.xml.sax.*;
 
 /**
Chuong trinh hien thi file XML nhu mot cay TreeView voi .DOM
 */
 public class DOMTreeTest
{
public static void main(String[] args)
 {
 JFrame frame = new DOMTreeFrame();
 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 frame.setVisible(true);
     }
  }
 
  /**
    Hien thi muc luc cua file XML theo dinh dang
 . */
  @SuppressWarnings("serial")
class DOMTreeFrame extends JFrame
  {
     public DOMTreeFrame()
     {
        setTitle("DOMTreeTest");
        setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
 
        JMenu fileMenu = new JMenu("File");
        JMenuItem openItem = new JMenuItem("Open");
        openItem.addActionListener(new
ActionListener()
           {
              public void actionPerformed(ActionEvent event) { openFile(); }
           });
        fileMenu.add(openItem);
 
        JMenuItem exitItem = new JMenuItem("Exit");
        exitItem.addActionListener(new
           ActionListener()
{
              public void actionPerformed(ActionEvent event) { System.exit(0); }
           });
        fileMenu.add(exitItem);
 
        JMenuBar menuBar = new JMenuBar();
        menuBar.add(fileMenu);
        setJMenuBar(menuBar);
    }
 
     /**
       Dong hoac mo file
     */
     public void openFile()
     {
        JFileChooser chooser = new JFileChooser();
        chooser.setCurrentDirectory(new File("."));
 
        chooser.setFileFilter(new
           javax.swing.filechooser.FileFilter()
           {
              public boolean accept(File f)
              {
                 return f.isDirectory() || f.getName().toLowerCase().endsWith(".xml");
              }
              public String getDescription() { return "XML files"; }
           });
        int r = chooser.showOpenDialog(this);
        if (r != JFileChooser.APPROVE_OPTION) return;
        File f = chooser.getSelectedFile();
        try
        {
           if (builder == null)
           {
              DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
              builder = factory.newDocumentBuilder();
           }
 
Document doc = builder.parse(f);
 JTree tree = new JTree(new DOMTreeModel(doc));
 tree.setCellRenderer(new DOMTreeCellRenderer());

           setContentPane(new JScrollPane(tree));
           validate();
        }
      catch (IOException e)
       {
 JOptionPane.showMessageDialog(this, e);
        }
        catch (ParserConfigurationException e)
        {
           JOptionPane.showMessageDialog(this, e);
      }
       catch (SAXException e)
       {
          JOptionPane.showMessageDialog(this, e);
       }
    }

    private DocumentBuilder builder;
   private static final int DEFAULT_WIDTH = 400;
    private static final int DEFAULT_HEIGHT = 400;
 }

/**
   Mo ta cau truc cua DOm
 */
 class DOMTreeModel implements TreeModel
 {
    /**
       Cau truc mo hinh 
       @param doc the document
    */
    public DOMTreeModel(Document doc) { this.doc = doc; }

    public Object getRoot() { return doc.getDocumentElement(); }

    public int getChildCount(Object parent)
    {
       Node node = (Node) parent;
       NodeList list = node.getChildNodes();
       return list.getLength();
    }

    public Object getChild(Object parent, int index)
    {
       Node node = (Node) parent;
       NodeList list = node.getChildNodes();
       return list.item(index);
    }

    public int getIndexOfChild(Object parent, Object child)
    {
       Node node = (Node) parent;
       NodeList list = node.getChildNodes();
      for (int i = 0; i < list.getLength(); i++)
          if (getChild(node, i) == child)
             return i;
       return -1;
    }

    public boolean isLeaf(Object node) { return getChildCount(node) == 0; }
    public void valueForPathChanged(TreePath path, Object newValue) {}
    public void addTreeModelListener(TreeModelListener l) {}
    public void removeTreeModelListener(TreeModelListener l) {}

    private Document doc;
 }

 /**
Phan lop node cua file XML
*/
@SuppressWarnings("serial")
class DOMTreeCellRenderer extends DefaultTreeCellRenderer
{
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus)
{
Node node = (Node) value;
if (node instanceof Element) return elementPanel((Element) node);
super.getTreeCellRendererComponent(tree, value,
selected, expanded, leaf, row, hasFocus);
if (node instanceof CharacterData)
setText(characterString((CharacterData) node));
else
setText(node.getClass() + ": " + node.toString());
return this;
}
public static JPanel elementPanel(Element e)
{
JPanel panel = new JPanel();
panel.add(new JLabel("Element: " + e.getTagName()));
panel.add(new JTable(new AttributeTableModel(e.getAttributes())));
return panel;
}
public static String characterString(CharacterData node)
{
StringBuilder builder = new StringBuilder(node.getData());
for (int i = 0; i < builder.length(); i++)
{
if (builder.charAt(i) == '\r')
{
builder.replace(i, i + 1, "\\r");
i++;
}
else if (builder.charAt(i) == '\n')
{
builder.replace(i, i + 1, "\\n");
i++;
}
else if (builder.charAt(i) == '\t')
{
builder.replace(i, i + 1, "\\t");
i++;
}
}
if (node instanceof CDATASection)
builder.insert(0, "CDATASection: ");
else if (node instanceof Text)
builder.insert(0, "Text: ");
else if (node instanceof Comment)
builder.insert(0, "Comment: ");
return builder.toString();
}
}
/**
Cac element cua file XML.
*/
@SuppressWarnings("serial")
class AttributeTableModel extends AbstractTableModel
{

public AttributeTableModel(NamedNodeMap map) { this.map = map; }
public int getRowCount() { return map.getLength(); }
public int getColumnCount() { return 2; }
   public Object getValueAt(int r, int c)
    {
       return c == 0 ? map.item(r).getNodeName() : map.item(r).getNodeValue();
    }
    private NamedNodeMap map;
 }


